﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SegIdenPC.Entidad;
using log4net;
using GS1.Utilitario;
using SegIdenPC.Herramientas;

namespace SegIdenPC.Formularios
{
    public partial class frmSolicitudBulto : Form
    {
        #region --- Variables y Propiedades ---
        private static readonly ILog log = LogManager.GetLogger(typeof(frmSolicitudBulto));

        private const string TITULO = "Generar Solicitud de Tranferencia Bultos";

        private const string FORMATO_PRODUCTO_DESCRIPCION_DETALLADA = "{0} - {1} - {2} - {3}";

        private Tienda tiendaOrigenActual = null;
        private Tienda tiendaDestinoActual = null;

        private Producto producto = null;
        #endregion

        #region --- Constructor ---
        public frmSolicitudBulto()
        {
            InitializeComponent();
        }
        #endregion

        #region --- Eventos Formulario ---
        private void frmSolicitudBulto_Load(object sender, EventArgs e)
        {
            cargarFormulario();
        }

        private void tbtnNuevo_Click(object sender, EventArgs e)
        {
            nuevo();
        }

        private void tbtnGrabar_Click(object sender, EventArgs e)
        {
            grabar();
        }

        private void tbtnSalir_Click(object sender, EventArgs e)
        {
            salir();
        }

        private void btnBuscarTiendaD_Click(object sender, EventArgs e)
        {
            elegirTiendaDestino();
        }

        private void btnBuscarProducto_Click(object sender, EventArgs e)
        {
            elegirProducto();
        }

        private void btnAgregar_Click(object sender, EventArgs e)
        {
            agregarBulto();
        }

        private void btnEliminar_Click(object sender, EventArgs e)
        {
            quitarBulto();
        }
        private void dgvListadoBultos_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            abrirBulto();
        }
        #endregion

        #region --- Metodos Propios ---
        private void cargarFormulario()
        {
            try
            {
                // Estableciendo tienda de origen
                if (!cargarTienda())
                {
                    this.tiendaOrigenActual = ParametrosAplicacion.ALMACEN_PRINCIPAL;
                    this.txtTiendaOCodigo.Text = this.tiendaOrigenActual.codigo;
                    this.txtTiendaODescripcion.Text = this.tiendaOrigenActual.descripcion;
                }

                // Estableciendo tienda de destino
                this.tiendaDestinoActual = ParametrosAplicacion.TIENDA_ACTUAL;
                this.txtTiendaDCodigo.Text = this.tiendaDestinoActual.codigo;
                this.txtTiendaDDescripcion.Text = this.tiendaDestinoActual.nombre;

                this.dtpFechaVencimiento.Value = DateTime.Now;
                this.btnBuscarTiendaO.Focus();
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }

        private void elegirTiendaDestino()
        {
            using (frmMantTienda frmMantTienda = new frmMantTienda())
            {
                frmMantTienda.formularioBusqueda = true;
                if (frmMantTienda.ShowDialog() == DialogResult.Cancel) { return; }

                this.tiendaDestinoActual = frmMantTienda.tiendaActual;
                this.txtTiendaDCodigo.Text = this.tiendaDestinoActual.codigo;
                this.txtTiendaDDescripcion.Text = this.tiendaDestinoActual.nombre;
            }
        }

        private void elegirProducto()
        {
            using (frmMantProducto frmMantProducto = new frmMantProducto())
            {
                frmMantProducto.formularioBusqueda = true;
                if (frmMantProducto.ShowDialog() == DialogResult.Cancel) { return; }

                this.producto = frmMantProducto.productoActual;

                // Mostrar los datos del producto
                this.txtProductoCodigo.Text = producto.codigo;
                this.txtProductoDescripcion.Text = string.Format(FORMATO_PRODUCTO_DESCRIPCION_DETALLADA, producto.nivelProducto.descripcion,
                                                                                                         producto.nivelTipo.descripcion,
                                                                                                         producto.nivelMaterial.descripcion,
                                                                                                         producto.nivelColor.descripcion);
            }

            obtenerBultos(this.producto);
        }

        private void obtenerBultos(Producto producto)
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            try
            {
                // Estableciendo operacion a ser enviada al Servicio REST
                operacion = new Operacion();
                operacion.numero = Constantes.OPERACION_LISTAR_BULTOS_PRODUCTO;

                operacion.producto = new Producto();
                operacion.producto.codigo = producto.codigo;

                // Instanciando y ejecutando llamada al ServicioREST
                ConexionREST conexionREST = new ConexionREST();
                contenidoXML = conexionREST.ejecutarOperacion(operacion);

                // Obteniendo Objeto de Error
                OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

                // Validar si hay error
                if (operacionError != null)
                {
                    Libreria.ShowMessageboxError(operacionError.descripcion);
                    return;
                }

                // Obteniendo Objeto de ListaItem
                ListaBulto listaBulto = contenidoXML.DeserializarTo<ListaBulto>();

                // Se establece propiedad para evitar que genere nuevas columnas que no estan mapeadas en la grilla
                this.dgvListadoBultos.AutoGenerateColumns = false;

                // Se establece la fuente de datos de la grilla
                this.dgvListadoBultos.DataSource = listaBulto.lista;

                // Validar si el producto tiene items disponibles
                if (listaBulto.lista.Count == 0)
                {
                    Libreria.ShowMessageboxExclamacion("El producto seleccionado, no tiene bultos disponibles", TITULO);
                }
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }

        private bool cargarTienda()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            try
            {
                // Estableciendo operacion a ser enviada al Servicio REST
                operacion = new Operacion();
                operacion.numero = Constantes.OPERACION_OBTENER_TIENDA;
                operacion.tienda = ParametrosAplicacion.ALMACEN_PRINCIPAL;

                // Instanciando y ejecutando llamada al ServicioREST
                ConexionREST conexionREST = new ConexionREST();
                contenidoXML = conexionREST.ejecutarOperacion(operacion);

                // Obteniendo Objeto de Error
                OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

                // Validar si hay error
                if (operacionError != null)
                {
                    Libreria.ShowMessageboxError(operacionError.descripcion);
                    return true;
                }

                // Obteniendo Objeto de Tienda
                Tienda tiendaObtenido = contenidoXML.DeserializarTo<Tienda>();
                ParametrosAplicacion.ALMACEN_PRINCIPAL = tiendaObtenido;

                if (tiendaObtenido == null)
                {
                    Libreria.ShowMessageboxExclamacion("Tienda no encontrado", Text);
                    return true;
                }
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex);

                Environment.Exit(0);
            }

            return false;
        }

        private bool validarItemRepetido(string codBulto)
        {
            bool resultato = false;

            // Obteniendo lista de items seleccionados
            ListPersonalizada<Bulto> listaBultosSeleccion = (ListPersonalizada<Bulto>)this.dgvListadoBultosSeleccionados.DataSource;

            if (listaBultosSeleccion != null)
            {
                foreach (Bulto bulto in listaBultosSeleccion)
                {
                    if (bulto.codBulto.Equals(codBulto))
                    {
                        resultato = true;
                        break;
                    }
                }
            }

            return resultato;
        }

        private bool validarAgregar()
        {
            this.txtProductoCodigo.Text = this.txtProductoCodigo.Text.Trim();
            this.txtProductoDescripcion.Text = this.txtProductoDescripcion.Text.Trim();

            if (this.txtProductoDescripcion.Text.Equals(string.Empty))
            {
                Libreria.ShowMessageboxExclamacion("Debe seleccionar un producto para agregar", TITULO);
                return true;
            }

            return false;
        }

        private void abrirBulto()
        {
            ListPersonalizada<Bulto> listaBultosSeleccion = null;

            listaBultosSeleccion = (ListPersonalizada<Bulto>)this.dgvListadoBultosSeleccionados.DataSource;

            if (listaBultosSeleccion == null) { listaBultosSeleccion = new ListPersonalizada<Bulto>(); }
            
            // Bulto Seleccionado
            Bulto bultoSeleccionado = listaBultosSeleccion[this.dgvListadoBultosSeleccionados.CurrentRow.Index];
            bultoSeleccionado = obtenerBulto(bultoSeleccionado);

            using (frmContenidoBulto frmContenidoBulto = new frmContenidoBulto())
            {
                frmContenidoBulto.bulto = bultoSeleccionado;
                frmContenidoBulto.ShowDialog();
                frmContenidoBulto.Dispose();
            }

        }

        private void agregarBulto()
        {
            ListPersonalizada<Bulto> listaBultos = null;
            ListPersonalizada<Bulto> listaBultosSeleccion = null;

            try
            {
                // Validar que el producto haya sido elegido
                if (validarAgregar()) { return; }

                // Capturando fuentes de datos de las grillas
                listaBultos = (ListPersonalizada<Bulto>)this.dgvListadoBultos.DataSource;
                listaBultosSeleccion = (ListPersonalizada<Bulto>)this.dgvListadoBultosSeleccionados.DataSource;

                if (listaBultosSeleccion == null) { listaBultosSeleccion = new ListPersonalizada<Bulto>(); }

                // Validar si el producto tiene Bultos disponibles
                if (listaBultos.Count == 0)
                {
                    Libreria.ShowMessageboxExclamacion("El producto actual, no tiene Bultos disponibles", TITULO);
                    return;
                }

                // Bulto Seleccionado
                Bulto bultoSeleccionado = listaBultos[this.dgvListadoBultos.CurrentRow.Index];

                // Valida si el item ya fue agregado
                if (validarItemRepetido(bultoSeleccionado.codBulto))
                {
                    Libreria.CampoNecesario(this.dgvListadoBultos, "Este Bulto ya se encuentra asociado a la solicitud", TITULO);
                    return;
                }

                // Instanciando Bulto a agregar
                Bulto bultoAgregar = new Bulto();
                bultoAgregar.codBulto = bultoSeleccionado.codBulto;
                bultoAgregar.SSCC = bultoSeleccionado.SSCC;
                bultoAgregar.estado = Constantes.ESTADO_BULTO_SOLICITADO;
                bultoAgregar.fechaRegistro = bultoSeleccionado.fechaRegistro;

                // Agregando item a listado de items seleccionados
                listaBultosSeleccion.Add(bultoAgregar);

                // Se establece propiedad para evitar que genere nuevas columnas que no estan mapeadas en la grilla
                this.dgvListadoBultosSeleccionados.AutoGenerateColumns = false;

                // Actualizando en grilla
                this.dgvListadoBultosSeleccionados.DataSource = null;
                this.dgvListadoBultosSeleccionados.DataSource = listaBultosSeleccion;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }

        private void quitarBulto()
        {
            ListPersonalizada<Bulto> listaBultosSeleccion = null;
            try
            {
                listaBultosSeleccion = (ListPersonalizada<Bulto>)this.dgvListadoBultosSeleccionados.DataSource;

                if (listaBultosSeleccion != null && listaBultosSeleccion.Count > 0)
                {
                    // Bulto Seleccionado
                    Bulto bultoSeleccionado = listaBultosSeleccion[this.dgvListadoBultosSeleccionados.CurrentRow.Index];

                    listaBultosSeleccion.Remove(bultoSeleccionado);

                    // Actualizando en grilla
                    this.dgvListadoBultosSeleccionados.DataSource = null;
                    this.dgvListadoBultosSeleccionados.DataSource = listaBultosSeleccion;
                }
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }

        private bool validarEntrada()
        {
            bool resultado = false;

            this.txtObservacion.Text = this.txtObservacion.Text.Trim();
            this.txtTiendaOCodigo.Text = this.txtTiendaOCodigo.Text.Trim();
            this.txtTiendaDCodigo.Text = this.txtTiendaDCodigo.Text.Trim();

            if (this.txtTiendaOCodigo.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtTiendaOCodigo, "Debe elegir una Tienda de Origén", TITULO);
                return true;
            }

            if (this.txtTiendaDCodigo.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtTiendaDCodigo, "Debe elegir una Tienda de Destino", TITULO);
                return true;
            }

            if (this.txtTiendaOCodigo.Text.Equals(this.txtTiendaDCodigo.Text))
            {
                Libreria.CampoNecesario(this.txtTiendaOCodigo, "La Tienda de Origen debe ser diferente a la Tienda Destino", TITULO);
                return true;
            }

            if (this.txtObservacion.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtObservacion, "Debe ingresar el campo Observación", TITULO);
                return true;
            }

            ListPersonalizada<Bulto> listaBulto = (ListPersonalizada<Bulto>)this.dgvListadoBultosSeleccionados.DataSource;

            if ((listaBulto == null) || (listaBulto!= null && listaBulto.Count == 0))
            {
                Libreria.CampoNecesario(this.dgvListadoBultosSeleccionados, "Debe ingresar por lo menos un Bulto a la Solicitud", TITULO);
                return true;
            }

            return resultado;
        }

        private void grabar()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            try
            {
                if (validarEntrada()) { return; }

                // Estableciendo operacion a ser enviada al Servicio REST
                operacion = new Operacion();
                operacion.numero = Constantes.OPERACION_REGISTRAR_SOLICITUD;

                operacion.solicitud = new Solicitud();
                operacion.solicitud.codSolicitud = Constantes.VALOR_CERO;

                // Estableciendo informacion de la tienda de Origen
                operacion.solicitud.tiendaOrigen = new Tienda();
                operacion.solicitud.tiendaOrigen.codigo = this.tiendaOrigenActual.codigo;
                operacion.solicitud.tiendaOrigen.nombre = this.tiendaOrigenActual.nombre;

                // Estableciendo informacion de la tienda de Destino
                operacion.solicitud.tiendaDestino = new Tienda();
                operacion.solicitud.tiendaDestino.codigo = this.tiendaDestinoActual.codigo;
                operacion.solicitud.tiendaDestino.nombre = this.tiendaDestinoActual.nombre;

                // Estableciendo el tipo de solicitud
                operacion.solicitud.tipo = Constantes.CODIGO_TIPO_SOLICITUD_BULTO;

                // Estableciendo usuario de registro
                operacion.solicitud.usuario = new Usuario();
                operacion.solicitud.usuario.codUsuario = ParametrosAplicacion.USUARIO_ACTUAL.codUsuario;

                operacion.solicitud.fechaVencimiento = this.dtpFechaVencimiento.Value.ToString(Constantes.FORMATO_FECHAHORA);
                operacion.solicitud.observacion = this.txtObservacion.Text;
                operacion.solicitud.estado = Constantes.ESTADO_DOCUMENTO_PENDIENTE;
                operacion.solicitud.fechaRegistro = DateTime.Now.ToString(Constantes.FORMATO_FECHAHORA);

                // Capturando listado de Bulto agregados
                ListPersonalizada<Bulto> listaBultoAgregados = (ListPersonalizada<Bulto>)this.dgvListadoBultosSeleccionados.DataSource;

                ListaLineaSolicitudBulto listaLineaSolicitudBulto = new ListaLineaSolicitudBulto();
                LineaSolicitudBulto lineaSolicitudBulto = null;

                foreach (Bulto bulto in listaBultoAgregados)
                {
                    lineaSolicitudBulto =  new LineaSolicitudBulto();
                    lineaSolicitudBulto.bulto = new Bulto { codBulto = bulto.codBulto, SSCC = bulto.SSCC, estado = bulto.estado };

                    listaLineaSolicitudBulto.add(lineaSolicitudBulto);
                }

                // Estableciendo listado de bultos
                operacion.solicitud.listaLineaSolicitudBulto = listaLineaSolicitudBulto;

                // Instanciando y ejecutando llamada al ServicioREST
                ConexionREST conexionREST = new ConexionREST();
                contenidoXML = conexionREST.ejecutarOperacion(operacion);

                // Obteniendo Objeto de Error
                OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

                // Validar si hay error
                if (operacionError != null)
                {
                    Libreria.ShowMessageboxError(operacionError.descripcion);
                    return;
                }

                OperacionResultado operacionResultado = contenidoXML.DeserializarTo<OperacionResultado>();

                if ((operacionResultado != null) &&
                    (operacionResultado.esOK.Equals(Constantes.SI)))
                {
                    this.txtCodigo.Text = operacionResultado.codigoGenerado;
                    Libreria.ShowMessageboxInfo("Registro guardado correctamente", TITULO);
                }
                else
                {
                    Libreria.ShowMessageboxError("No se guardo los datos", TITULO);
                    return;
                }

                // Estableciendo los estados de los botones
                this.grpDatos.Enabled = false;
                this.tbtnGrabar.Enabled = false;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }

        private void nuevo()
        {
            // Activando grupo para modificar campos
            this.grpDatos.Enabled = true;
            this.tbtnGrabar.Enabled = true;

            // Limpiando los datos del formulario
            this.txtCodigo.Text = string.Empty;

            this.txtProductoCodigo.Text = string.Empty;
            this.txtProductoDescripcion.Text = string.Empty;

            // Limpiando grilla de detalle de Items
            ListPersonalizada<Bulto> listaBultos = (ListPersonalizada<Bulto>)this.dgvListadoBultos.DataSource;
            ListPersonalizada<Bulto> listaBultosSeleccion = (ListPersonalizada<Bulto>)this.dgvListadoBultosSeleccionados.DataSource;

            if (listaBultos != null)
            {
                listaBultos.Clear();

                this.dgvListadoBultos.DataSource = null;
                this.dgvListadoBultos.DataSource = listaBultos;
            }

            if (listaBultosSeleccion != null)
            {
                listaBultosSeleccion.Clear();

                this.dgvListadoBultosSeleccionados.DataSource = null;
                this.dgvListadoBultosSeleccionados.DataSource = listaBultosSeleccion;
            }

            // Estableciendo focus al boton buscar producto
            this.btnBuscarProducto.Focus();
        }

        private void salir()
        {
            this.Close();
        }

        private Bulto obtenerBulto(Bulto bulto)
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            try
            {
                // Estableciendo operacion a ser enviada al Servicio REST
                operacion = new Operacion();
                operacion.numero = Constantes.OPERACION_OBTENER_BULTO_CONTENIDO;

                operacion.bulto = new Bulto();
                operacion.bulto = bulto;

                // Instanciando y ejecutando llamada al ServicioREST
                ConexionREST conexionREST = new ConexionREST();
                contenidoXML = conexionREST.ejecutarOperacion(operacion);

                // Obteniendo Objeto de Error
                OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

                // Validar si hay error
                if (operacionError != null)
                {
                    Libreria.ShowMessageboxError(operacionError.descripcion);
                    return bulto;
                }

                // Obteniendo Objeto de ListaItem
                Bulto bultoEncontrado = contenidoXML.DeserializarTo<Bulto>();

                return bultoEncontrado;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
                return bulto;
            }
        }
        #endregion


    }
}
